package com.smartalarmclock.Model;

import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import android.content.Context;

import com.smartalarmclock.Model.Exceptions.DataEntityDoesNotExistException;
import com.smartalarmclock.Model.ILogEntry.PhoneEvent;

public final class LogEntryFactory implements IReferencingDataEntityFactory {

	/**
	 * Creates a new log entry in the log using a SingleContact
	 * @param event the phone event (incoming call or SMS)
	 * @param sentToAnsweringMachine whether the call was sent to the answering machine
	 * @param contact the single contact in the event
	 * @param rulesItem the rules item which handled the event
	 * @param sentSMS the SMS sent automatically
	 */
	public ILogEntry CreateLogEntry(
		PhoneEvent event,
		boolean sentToAnsweringMachine,
		ISingleContact contact,
		IRulesItem rulesItem,
		String sentSMS) {
		return new LogEntry(event, sentToAnsweringMachine, contact, rulesItem, sentSMS);
	}
	
	/**
	 * Creates a new log entry in the log using a phone number
	 * @param event the phone event (incoming call or SMS)
	 * @param sentToAnsweringMachine whether the call was sent to the answering machine
	 * @param phoneNumber the phone number of the event
	 * @param rulesItem the rules item which handled the event
	 * @param sentSMS the SMS sent automatically
	 */
	public ILogEntry CreateLogEntry(
		PhoneEvent event,
		boolean sentToAnsweringMachine,
		String phoneNumber,
		IRulesItem rulesItem,
		String sentSMS) {
		return new LogEntry(event, sentToAnsweringMachine, phoneNumber, rulesItem, sentSMS);
	}
	
	/**
	 * Queries the DB for a log entry by id
	 * @param context the context of the request
	 * @param id the id to query for
	 * @return a matching LogEntry instance
	 * @throws DataEntityDoesNotExistException if the data entity does not exist.
	 */
	public ILogEntry GetLogEntryById(Context context, int id) throws DataEntityDoesNotExistException {
		return LogEntry.GetLogEntryById(context, id);
	}
	
	/**
	 * Queries the DB for a log entry by id
	 * @param context the context of the request
	 * @param id the id to query for
	 * @return a matching LogEntry instance or null if the entity does not exist
	 */
	public ILogEntry TryGetLogEntryById(Context context, int id) {
		return TryGetLogEntryById(context, id);
	}
	
	/**
	 * Queries the DB for all log entries by single contact
	 * @param context the context of the request
	 * @param contact the contact to query for
	 * @return all matching LogEntry instances
	 */
	public Set<ILogEntry> GetLogEntriesBySingleContact(Context context, ISingleContact contact) {
		return LogEntry.GetLogEntriesBySingleContact(context, contact);
	}
	
	/**
	 * Queries the DB for all log entries by the handling rules item
	 * @param context the context of the request
	 * @param rulesItem the handling rules item
	 * @return all matching LogEntry instances
	 */
	public Set<ILogEntry> GetLogEntriesByRulesItem(Context context, IRulesItem rulesItem) {
		return LogEntry.GetLogEntriesByRulesItem(context, rulesItem);
	}
	
	/**
	 * Queries the DB for all log entries in the given time range
	 * @param context the context of the request
	 * @param startTime the start time of the time range
	 * @param endTime the end time of the time range
	 * @return all matching LogEntry instances
	 */
	public Set<ILogEntry> GetLogEntriesByTimeRange(Context context, Date startTime, Date endTime) {
		return LogEntry.GetLogEntriesByTimeRange(context, startTime, endTime);
	}
	
	@Override
	public Set<IReferencingDataEntity> GetReferencingEntities(Context context, IReferencedDataEntity referencedDataEntity) throws DataEntityDoesNotExistException {
		Set<IReferencingDataEntity> referencingEntities = new HashSet<IReferencingDataEntity>();
		
		if (ISingleContact.class.isInstance(referencedDataEntity)) {
			referencingEntities.addAll(GetLogEntriesBySingleContact(context, (ISingleContact)referencedDataEntity));
		}
		else if (IRulesItem.class.isInstance(referencedDataEntity)) {
			referencingEntities.addAll(GetLogEntriesByRulesItem(context, (IRulesItem)referencedDataEntity));
		}
		
		return referencingEntities;
	}
}
